#!/usr/bin/python

"""A small http server that fetches temperature data from an arduino via
serial port."""

import BaseHTTPServer
import os
import threading
import time

class TemperatureData(object):
  singleton = object()
 
  def __init__(self):
    self.device_data_by_id = {}
    self.device_name_by_id = {}
    self.lock = threading.Lock()

  def Append(self, device_id, device_name, temperature):
    self.lock.acquire()
    if device_id not in self.device_name_by_id:
      self.device_name_by_id[device_id] = device_name
    previous = self.device_data_by_id.get(device_id, [])
    previous.append(float(temperature))
    if len(previous) > 2048:
      previous = previous[:1024]
    self.device_data_by_id[device_id] = previous
    self.lock.release()

  def GetMinMaxAvgPerDevice(self):
    self.lock.acquire()
    ret = {}
    for id in self.device_name_by_id:
      name = self.device_name_by_id[id]
      data = self.device_data_by_id[id]
      ret[name] = {'min': min(data),
                   'max': min(data),
                   'avg': sum(data) / len(data),
                   'count': len(data)}
    self.lock.release()
    return ret


class TemperatureFetcher(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    serial_name = '/dev/ttyUSB0'
    if not os.path.exists(serial_name):
      serial_name = '/dev/ttyUSB1'
    self.serial = file(serial_name, 'r')
    self.interrupted = False

  def run(self):
    while not self.interrupted:
      line = self.serial.readline()
      elements = line.split(',')
      if len(elements) == 10:
        device_id = ','.join(elements[0:7])
        device_name = elements[8]
        temperature = elements[9]
        TemperatureData.singleton.Append(device_id, device_name, temperature)
      time.sleep(5)
 

class TemperatureDisplayer(BaseHTTPServer.BaseHTTPRequestHandler):
  def do_GET(self):
    data = '<html><body><table><tr><td>Area</td><td>Min</td><td>Max</td><td>Avg</td><td>Count</td></tr>'
    sensors = TemperatureData.singleton.GetMinMaxAvgPerDevice() 
    for d in sensors:
      data += ('<tr><td>%s</td><td>%.2f</td><td>%.2f</td><td>%.2f</td><td>%d</td></tr>' %
               (d, sensors[d]['min'], sensors[d]['max'], 
                sensors[d]['avg'], sensors[d]['count']))
    data += '</table></body></html>'
    self.wfile.write(data)


def main():
  TemperatureData.singleton = TemperatureData()
  fetcher = TemperatureFetcher()
  try:
    fetcher.start()
    server = BaseHTTPServer.HTTPServer(('', 9000), TemperatureDisplayer)
    server.serve_forever()
  except:
    fetcher.interrupted = True
    server.socket.close()


if __name__ == '__main__':
  main()